package com.travel.rabbit.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.travel.rabbit.dao.DistrictMapper;
import com.travel.rabbit.entity.District;
import com.travel.rabbit.enums.DistrictEnum;
import com.travel.rabbit.service.DistrictService;
import com.travel.rabbit.utils.RedisUtils;
import com.travel.rabbit.dto.DistrictDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 中国行政区划代码表
数据时间：2019年11月
数据来源：http://www.mca.gov.cn/article/sj/xzqh(District)表服务实现类
 *
 * @author makejava
 * @since 2021-12-27 17:21:45
 */
@Service("districtService")
public class DistrictServiceImpl implements DistrictService {

    @Resource
    private DistrictMapper districtDao;

    @Resource
    private RedisUtils redisUtils;

    @Override
    public District queryById(String id){
        return this.districtDao.selectOne(Wrappers.<District>lambdaQuery().eq(District::getId, id));
    }

    @Override
    public String queryNameById(String id){
        id = StringUtils.rightPad(id, 6, "0");
        District district = this.queryById(id);
        return Objects.isNull(district) ?  "" : district.getName();
    }

    /**
     * 通过ID查询单条数据
     *
     * @param pid 主键
     * @return 实例对象
     */
    @Override
    public List<DistrictDTO> queryByPId(Integer pid) {
        List<DistrictDTO> result;
        String districtPidKey = "district_pid_key" + pid;
        Set o = redisUtils.setMembers(districtPidKey);
        if (CollectionUtils.isEmpty(o)) {
            result = queryByPid(pid);
            if (CollectionUtils.isEmpty(result)) {
                return new ArrayList<>();
            } else {
                redisUtils.add(districtPidKey, result);
            }
        } else {
            result = new ArrayList<>(o);
        }
        return result;
    }

    

    @Override
    public List<DistrictDTO> firstDistrict() {
        List<DistrictDTO> result = new ArrayList<>();
        String districtFirstLevelKey = "district_first_key";
        Set o = redisUtils.setMembers(districtFirstLevelKey);
        if (CollectionUtils.isEmpty(o)) {
            List<District> first = first();
            for (District v : first) {
                DistrictDTO info = new DistrictDTO();
                BeanCopier beanCopier = BeanCopier.create(District.class, DistrictDTO.class, false);
                beanCopier.copy(v, info, null);
                result.add(info);
            }
            redisUtils.add(districtFirstLevelKey, result);
        } else {
            result = new ArrayList<>(o);
        }
        return result;
    }

    @Override
    public void cache() {
        List<District> first = this.districtDao.selectList(Wrappers.<District>lambdaQuery()
                .eq(District::getLevel, DistrictEnum.FIRST.getCode()));
        if (!CollectionUtils.isEmpty(first)) {
            for (District one: first){
                String firstKey = "district_pid_key"+one.getId()+"::"+one.getName()+"::"+one.getLevel();
                List<DistrictDTO> second = this.queryByPid(one.getId());
                if (!CollectionUtils.isEmpty(second)){
                    redisUtils.add(firstKey,second);
                }
            }
        }

        List<District> second = this.districtDao.selectList(Wrappers.<District>lambdaQuery().eq(District::getLevel, DistrictEnum.SECOND.getCode()));
        if (!CollectionUtils.isEmpty(second)) {
            for (District two: second){
                String secondKey = "district_pid_key"+two.getId()+"::"+two.getName()+"::"+two.getLevel();
                List<DistrictDTO> three = this.queryByPid(two.getId());
                if (!CollectionUtils.isEmpty(three)){
                    redisUtils.add(secondKey,three);
                }
            }
        }
    }

    private List<District> first(){
        return  this.districtDao.selectList(Wrappers.<District>lambdaQuery().eq(District::getLevel, DistrictEnum.FIRST.getCode()));
    }

    private List<DistrictDTO> queryByPid(Integer pid){
        List<District> districts = this.districtDao.selectList(Wrappers.<District>lambdaQuery().eq(District::getUpid, pid));
        if (CollectionUtils.isEmpty(districts)){
            return new ArrayList<>();
        }
        List<DistrictDTO> result = new ArrayList<>();
        districts.stream().forEach(v->{
            DistrictDTO info = new DistrictDTO();
            BeanCopier beanCopier = BeanCopier.create(District.class, DistrictDTO.class, false);
            beanCopier.copy(v, info, null);
            result.add(info);
        });
        return result;
    }

}